﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using PhotoResizer;

namespace PhotoResizer
{
    public partial class Form1 : Form
    {
        #region Global Variables
        public Size size = new Size();
        private Bitmap image, dest;
        static DateTime startTime, endTime;
        #endregion

        #region I/p and O/p Folders Button Clicks

        private void BtnBrowseIp_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                foreach (String filename in openFileDialog1.FileNames)
                {
                    if (!listBox1.Items.Contains(filename))
                    {
                        listBox1.Items.Add(filename);
                        //listBox2.Items.Add(filename.Substring(filename.LastIndexOf('\\') + 1));
                    }
                }
            }

            lblStatus.Text = listBox1.Items.Count.ToString() + " files are Loaded.";
            lblCount.Text = listBox1.Items.Count.ToString();
        }

        private void BtnBrowseOp_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                txtBoxOpPath.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        #endregion

        #region User Input Validation
        private void txtBoxQuality_KeyPress(object sender, KeyPressEventArgs e)
        {
            numericError(e);
        }

        private void txtBoxHt1_KeyPress(object sender, KeyPressEventArgs e)
        {
            numericError(e);
        }

        private void txtBoxWt1_KeyPress(object sender, KeyPressEventArgs e)
        {
            numericError(e);
        }

        private void numericError(KeyPressEventArgs e)
        {
            if (e.KeyChar >= 48 && e.KeyChar <= 57 || e.KeyChar == 8)
            {
                e.Handled = false;
            }
            else
            {
                MessageBox.Show("Please Enter only Numbers", "Alert Message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                e.Handled = true;
            }
        }

        private void isQualityBound(KeyEventArgs e)
        {
            int quality = Convert.ToInt32(txtBoxQuality.Text);
            if (quality < 0 || quality > 100)
            {
                MessageBox.Show("Please enter quality between 0-100 only", "Alert Message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                e.Handled = true;
            }
            else
            {
                e.Handled = false;
            }
        }

        private void txtBoxQuality_KeyUp(object sender, KeyEventArgs e)
        {
            isQualityBound(e);
        }
        #endregion

        #region Size and Proportion Functions
        private void rdBtnResize1_CheckedChanged(object sender, EventArgs e)
        {
            if (rdBtnResize1.Checked == true)
            {
                groupBox3.Text = "Resize by Proportion";
                label9.Text = "%";
                label10.Text = "%";
                txtBoxHt1.Text = "100";
                txtBoxWt1.Text = "100";
                chkBoxScale1.Checked = true;
            }
            else
            {
                groupBox3.Text = "Resize by Pixels";
                label9.Text = "px";
                label10.Text = "px";
                txtBoxHt1.Text = "200";
                txtBoxWt1.Text = "200";
                chkBoxScale1.Checked = true;
            }
        }

        private void txtBoxHt1_TextChanged(object sender, EventArgs e)
        {
            if (chkBoxScale1.Checked == true)
            {
                txtBoxWt1.Text = txtBoxHt1.Text;
            }
        }

        private void chkBoxScale1_CheckedChanged(object sender, EventArgs e)
        {
            if (chkBoxScale1.Checked == true)
            {
                txtBoxWt1.Text = txtBoxHt1.Text;
            }
        }

        private void txtBoxWt1_TextChanged(object sender, EventArgs e)
        {
            if (chkBoxScale1.Checked == true)
            {
                txtBoxHt1.Text = txtBoxWt1.Text;
            }
        }

        private void initialiseSize()
        {
            //take % or px
            size.Height = Convert.ToInt32(txtBoxHt1.Text);
            size.Width = Convert.ToInt32(txtBoxWt1.Text);
        }
        #endregion

        #region BackGroundWorker Functions

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            string opPath = txtBoxOpPath.Text;

            int count = listBox1.Items.Count;
            int progress = 0, counter = 0;
            string userstate;
            //Files Found !

            initialiseSize();

            foreach (String srcFilename in listBox1.Items)
            {
                //the following line works only with .NET 2.0 SP1
                //string srcFilename = txtBoxIpPath.Text + @"\" + System.IO.Path.GetFileNameWithoutExtension(filename) + ".jpg";

                //check dimentions

                if ((backgroundWorker1.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }

                try
                {
                    image = new Bitmap(srcFilename);
                }
                catch
                {
                    MessageBox.Show("Error loading bitmap : " + srcFilename, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                if (rdBtnResize1.Checked == true)
                {
                    //take %
                    dest = scaleBitmapByPercent(image, size.Height, size.Width); //Size.x -> in %age
                }
                else
                {
                    //take px
                    dest = new Bitmap(size.Width, size.Height);
                    dest = resizeImage(image, size);
                    //scaleBitmap(dest, image);
                }

                string destFilename = txtBoxOpPath.Text + @"\" + System.IO.Path.GetFileNameWithoutExtension(srcFilename) + ".jpg";
                try
                {
                    //saveJpeg(string path, Bitmap img, long quality)
                    saveJpeg(destFilename, dest, (long)Convert.ToInt32(txtBoxQuality.Text));
                    //dest.Save(destFilename, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                catch
                {
                    MessageBox.Show("Error saving bitmap : " + destFilename, "Alert Message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                counter++;

                userstate = "Completed resizing " + counter + " files...";
                progress = counter * 100 / count;
                backgroundWorker1.ReportProgress(progress, userstate);
            }

            if (chkBoxZip.Checked == true)
            {
                //zip the output folder
                zipFolder();
            }

            //open the output directory
            System.Diagnostics.Process.Start(txtBoxOpPath.Text);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            lblStatus.Text = e.UserState.ToString();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            TimeSpan duration;
            endTime = DateTime.Now;
            duration = endTime - startTime;

            if ((e.Cancelled == true))
            {
                lblStatus.Text = "Canceled! Total Time taken: " + duration.TotalSeconds + " seconds";
            }

            else if (!(e.Error == null))
            {
                lblStatus.Text = ("Error: " + e.Error.Message);
            }

            else
            {
                lblStatus.Text = "Successfully resized images. Total Time taken: " + duration.TotalSeconds + " seconds";
                progressBar.Value = 0;
                progressBar.Visible = false;
            }
        }

        private void BtnCancel_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
        }

        #endregion

        #region Helper Functions

        private void zipFolder()
        {
            try
            {
                HelperClasses.zipFolder(txtBoxOpPath.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Zip Operation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private static Bitmap resizeImage(Bitmap imgToResize, Size size)
        {
            return HelperClasses.resizeImage(imgToResize, size);
        }

        private Bitmap scaleBitmapByPercent(Bitmap src, int HieghtPg, int WidthPg)
        {
            return HelperClasses.scaleBitmapByPercent(src, HieghtPg, WidthPg);
        }

        private void saveJpeg(string path, Bitmap img, long quality)
        {
            HelperClasses.saveJpeg(path, img, quality);
        }

        #endregion

        #region Menu Strip
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void whatsNewToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            NewFeatures f1 = new NewFeatures();
            f1.ShowDialog();
        }

        private void aboutPhotoReToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox f = new AboutBox();
            f.ShowDialog();
        }

        private void helpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://photoresizer.bhavikvora.com/help.aspx");
        }

        private void feedbackToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //WebService Reference
            Feedback a = new Feedback();
            a.Show();
        }

        private void visitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://photoresizer.bhavikvora.com");
        }

        private void checkForUpdateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CheckUpdate a = new CheckUpdate();
            a.Show();
        }

        #endregion

        #region Events

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            lblStatus.Text = "Application Started";
            progressBar.Visible = false;
            txtBoxOpPath.Text = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
        }

        private void BtnResize_Click(object sender, EventArgs e)
        {


            string opPath = txtBoxOpPath.Text;
            if (System.IO.Directory.Exists(opPath))
            {
                if (listBox1.Items.Count == 0)
                {
                    MessageBox.Show("No Files to be resized.", "Alert Message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    //Files Found !
                    startTime = DateTime.Now;
                    BtnResize.Enabled = false;
                    progressBar.Visible = true;
                    progressBar.Value = 0;
                    backgroundWorker1.RunWorkerAsync(); //call the bgworker dowork method
                    progressBar.Value = 0;
                    progressBar.Visible = false;
                    BtnResize.Enabled = true;
                }
            }
            else
            {
                MessageBox.Show("Please select a valid Output Path", "Alert Message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnRemoveFile_Click(object sender, EventArgs e)
        {
            listBox1.Items.RemoveAt(listBox1.SelectedIndex);
            lblStatus.Text = "Removed 1 file. Files in selection: " + listBox1.Items.Count;
        }

        private void btnClearFiles_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            lblCount.Text = listBox1.Items.Count.ToString();
        }

        private void listBox1_DragEnter(object sender, DragEventArgs e)
        {
            // make sure they're actually dropping files (not text or anything else)
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
                e.Effect = DragDropEffects.All;
        }

        private void listBox1_DragDrop(object sender, DragEventArgs e)
        {
            // transfer the filenames to a string array
            // (yes, everything to the left of the "=" can be put in the 
            // foreach loop in place of "files", but this is easier to understand.)
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

            // loop through the string array, adding each filename to the ListBox
            foreach (string file in files)
            {
                if (file.EndsWith(".jpg") || file.EndsWith(".jpeg") || file.EndsWith(".bmp") || file.EndsWith(".png") || file.EndsWith(".JPG") || file.EndsWith(".JPEG") || file.EndsWith(".BMP") || file.EndsWith(".PNG"))
                {
                    if (!listBox1.Items.Contains(file))
                    {
                        listBox1.Items.Add(file);
                        lblCount.Text = listBox1.Items.Count.ToString();
                    }
                }
                else
                {
                    MessageBox.Show("Only jpg, bmp and png files can be processed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void listBox1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                //remove selected item from list
                while (listBox1.SelectedItem != null)
                {
                    listBox1.Items.Remove(listBox1.SelectedItem);
                }
                lblStatus.Text = "Removed selected files."; // Files in selection: " + listBox1.Items.Count;
                lblCount.Text = listBox1.Items.Count.ToString();
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                pbThumbnail.ImageLocation = listBox1.SelectedItem.ToString();
            }
            catch (Exception ex)
            {

            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.Visible == true)
            {
                this.Hide();
            }
            else if (this.Visible == false)
            {
                this.Show();
            }
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.Show();
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void listBox1_MouseMove(object sender, MouseEventArgs e)
        {
            //if (sender is ListBox)
            //{
            //    int i = listBox1.IndexFromPoint(e.X, e.Y);
            //    if (i >= 0 && i < listBox1.Items.Count)
            //    {
            //        String str = listBox1.Items[i].ToString();
            //        Graphics g = listBox1.CreateGraphics();

            //        if(g.MeasureString(str, listBox1.Font).Width < listBox1.ClientRectangle.Width)
            //            toolTip1.SetToolTip(listBox1, str);
            //        else
            //            toolTip1.SetToolTip(listBox1, "");
            //        g.Dispose();
            //    }
            //}
        }

        #endregion
    }
}
